home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac Mania 5
/
MacMania 5.toast
/
/
Internet software
/
NewsWatcher
/
NW Source
/
Source
/
help.c
< prev
next >
Wrap
Text File
|
1997-01-09
|
28KB
|
1,124 lines
/*----------------------------------------------------------------------------
help.c
This module handles the help topic windows. It also exports some
utility functions for displaying help balloons.
Copyright © 1994-1997, Northwestern University.
----------------------------------------------------------------------------*/
#include "Icons.h"
#include "string.h"
#include "ctype.h"
#include "glob.h"
#include "help.h"
#include "menus.h"
#include "resutil.h"
#include "wind.h"
#include "dialog.h"
#include "newswatcher.h"
#include "memutil.h"
#include "windutil.h"
#include "key.h"
#include "iconutil.h"
#include "fileutil.h"
#include "strutil.h"
#include "sfutil.h"
#include "drawutil.h"
#include "print.h"
#include "status.h"
#include "menuutil.h"
#define kMinWindowWidth 299 /* minimum window width */
#define kMinWindowHeight 85 /* minimum window height */
#define kPanelHeight 22 /* panel height */
#define kFirstHelpMenuPictResourceID 1000 /* Resource id of first 'PICT'
resource for help topics */
#define kDynamicWindowStringsResourceID 133 /* STR# resource id for dynamic window
balloon help strings */
static short gNumStandardHelpMenuItems; /* number of items in standard system
Help menu */
static short gNumHelpTopics = 0; /* number of items we added to
Help menu */
static ControlActionUPP gScrollActionUPP;
/*----------------------------------------------------------------------------
ShowHelpBalloon
Display a help balloon for a dynamic window.
Entry: tip = location of tip in local coordinates. If {0,0}, the middle
of the alternateRect is used as the tip.
alternateRect = pointer to alternate rectangle in local coordinates.
index = index in kDynamicWindowStringsResourceID STR# resource of
help string.
----------------------------------------------------------------------------*/
void ShowHelpBalloon (Point tip, Rect *alternateRect, short index)
{
HMMessageRecord helpMsg;
Rect r;
if (tip.h == 0 && tip.v == 0) {
tip.h = (alternateRect->left + alternateRect->right) >> 1;
tip.v = (alternateRect->top + alternateRect->bottom) >> 1;
}
LocalToGlobal(&tip);
r = *alternateRect;
LocalToGlobalRect(&r);
helpMsg.hmmHelpType = khmmStringRes;
helpMsg.u.hmmStringRes.hmmResID = kDynamicWindowStringsResourceID;
helpMsg.u.hmmStringRes.hmmIndex = index;
HMShowBalloon(&helpMsg, tip, &r, nil, 0, 1, kHMRegularWindow);
}
/*----------------------------------------------------------------------------
DoSizeBoxAndVerticalScrollBarBalloons
Handle help balloons for the size box and vertical scroll bar in a
window.
Entry: wind = pointer to window.
where = current mouse location in local coordinates.
Exit: function result = true if help balloon drawn.
----------------------------------------------------------------------------*/
Boolean DoSizeBoxAndVerticalScrollBarBalloons (WindowPtr wind, Point where)
{
Rect r;
Point tip = {0, 0};
TWindow **info;
ControlHandle vScroll;
r = wind->portRect;
r.left = r.right - 15;
r.top = r.bottom - 15;
if (PtInRect(where, &r)) {
ShowHelpBalloon(tip, &r, 1);
return true;
}
info = (TWindow**)GetWRefCon(wind);
vScroll = (**info).vScroll;
if (vScroll == nil) return false;
r = (**vScroll).contrlRect;
if (PtInRect(where, &r)) {
ShowHelpBalloon(tip, &r, (**vScroll).contrlMax > 0 ? 2 : 3);
return true;
}
return false;
}
/*----------------------------------------------------------------------------
KillBalloon
Remove any help balloon which may be currently displayed on the screen.
----------------------------------------------------------------------------*/
void KillBalloon (void)
{
if (!gInBackground && HMGetBalloons() && HMIsBalloon()) HMRemoveBalloon();
}
/*----------------------------------------------------------------------------
InitHelpMenu
Initialize the Help menu topics.
----------------------------------------------------------------------------*/
void InitHelpMenu (void)
{
MenuHandle helpMenu;
OSErr err = noErr;
short i, theID;
Handle h;
ResType theType;
Str255 name;
err = MyHMGetHelpMenuHandle(&helpMenu);
if (err != noErr) return;
gNumStandardHelpMenuItems = CountMItems(helpMenu);
SetResLoad(false);
for (i = kFirstHelpMenuPictResourceID; ; i++) {
err = MyGet1Resource('PICT', i, &h);
if (err != noErr) break;
GetResInfo(h, &theID, &theType, name);
AppendMenu(helpMenu, name);
}
SetResLoad(true);
gNumHelpTopics = i - kFirstHelpMenuPictResourceID;
}
/*----------------------------------------------------------------------------
AdjustHelpMenu
Adjust the Help menu (enable/disable our extra commands).
----------------------------------------------------------------------------*/
void AdjustHelpMenu (void)
{
TWindowKind kind;
Boolean enabled;
short i;
MenuHandle helpMenu;
OSErr err = noErr;
kind = GetMyWindowKind(FrontWindow());
enabled = kind != kDialog && !gLongOperation;
err = MyHMGetHelpMenuHandle(&helpMenu);
if (err != noErr) return;
for (i = 1; i <= gNumHelpTopics; i++) {
if (enabled) {
EnableItem(helpMenu, gNumStandardHelpMenuItems + i);
} else {
DisableItem(helpMenu, gNumStandardHelpMenuItems + i);
}
}
}
/*----------------------------------------------------------------------------
CheckHelpWindowAlreadyOpen
Check to see if a help window is already open, and if it is, bring it to
the front.
Entry: pictResID = 'PICT' resource id for window.
Exit: function result = true if already open window brought to front.
----------------------------------------------------------------------------*/
static Boolean CheckHelpWindowAlreadyOpen (short pictResID)
{
WindowPtr wind;
TWindowKind kind;
TWindow **info;
wind = FrontWindow();
while (wind != nil) {
kind = GetMyWindowKind(wind);
if (kind == kHelp) {
info = (TWindow**)GetWRefCon(wind);
if (pictResID == (**info).pictResID) {
MySelectWindow(wind);
return true;
}
}
wind = (WindowPtr)(((WindowPeek)wind)->nextWindow);
}
return false;
}
/*----------------------------------------------------------------------------
AdjustScrollMax
Adjust the max scroll bar value.
Entry: wind = pointer to help window.
----------------------------------------------------------------------------*/
static void AdjustScrollMax (WindowPtr wind)
{
TWindow **info;
PicHandle pict;
Rect picFrame;
ControlHandle vScroll;
short picHeight, viewHeight, pos, max;
info = (TWindow**)GetWRefCon(wind);
pict = GetPicture((**info).pictResID);
picFrame = (**pict).picFrame;
vScroll = (**info).vScroll;
picHeight = picFrame.bottom - picFrame.top;
viewHeight = wind->portRect.bottom - 15 - 2*kTextMargin - kPanelHeight;
pos = GetControlValue(vScroll);
if (pos + viewHeight > picHeight) picHeight = pos + viewHeight;
max = picHeight - viewHeight;
if (max < 0) max = 0;
SetControlMaximum(vScroll, max);
}
/*----------------------------------------------------------------------------
Scroll
Scroll a help window.
Entry: wind = pointer to help window.
dv = number of pixels to scroll.
If the scroll bar's refCon is non-zero, the scroll bar max value is
adjusted after the scrolling operation. This is what you normally want.
The only exception is when scrolling in a TrackControl action procedure,
when you want to set the refCon to zero.
----------------------------------------------------------------------------*/
static void Scroll (WindowPtr wind, short dv)
{
TWindow **info;
ControlHandle vScroll;
Rect r;
RgnHandle updateRgn;
info = (TWindow**)GetWRefCon(wind);
vScroll = (**info).vScroll;
r = wind->portRect;
r.top += kPanelHeight;
r.right -= 15;
r.bottom -= 15;
InsetRect(&r, kTextMargin, kTextMargin);
updateRgn = NewRgn();
ScrollRect(&r, 0, dv, updateRgn);
InvalRgn(updateRgn);
DisposeRgn(updateRgn);
if (GetControlReference(vScroll) != 0) AdjustScrollMax(wind);
}
/*----------------------------------------------------------------------------
ScrollByPartCode
Scroll a help window by part code.
Entry: wind = pointer to help window.
part = part code.
----------------------------------------------------------------------------*/
static void ScrollByPartCode (WindowPtr wind, short part)
{
TWindow **info;
ControlHandle vScroll;
short val, max, page, dv;
info = (TWindow**)GetWRefCon(wind);
vScroll = (**info).vScroll;
page = wind->portRect.bottom - 15 - 2*kTextMargin - 15;
val = (**vScroll).contrlValue;
max = (**vScroll).contrlMax;
dv = 0;
switch (part) {
case inUpButton:
dv = 15;
break;
case inDownButton:
dv = -15;
break;
case inPageUp:
dv = page;
break;
case inPageDown:
dv = -page;
break;
case kScrollToHome:
dv = val;
break;
case kScrollToEnd:
dv = val - max;
break;
}
if (val - dv < 0) {
dv = val;
} else if (val - dv > max) {
dv = val - max;
}
if (dv != 0) {
Scroll(wind, dv);
AdjustScrollMax(wind);
SetControlValue(vScroll, val - dv);
}
}
/*----------------------------------------------------------------------------
ScrollAction
Vertical scroll bar action proc.
Entry: vScroll = handle to vertical scroll bar control.
part = part code.
----------------------------------------------------------------------------*/
static pascal void ScrollAction (ControlHandle vScroll, short part)
{
WindowPtr wind;
wind = (**vScroll).contrlOwner;
ScrollByPartCode(wind, part);
HandleUpdate(wind);
}
/*----------------------------------------------------------------------------
DoHelpMenuCommand
Do a Help menu command.
Entry: item = item number in Help menu.
Exit: function result = error code.
----------------------------------------------------------------------------*/
OSErr DoHelpMenuCommand (short item)
{
short pictResID;
OSErr err = noErr;
PicHandle pict;
short theID;
ResType theType;
Str255 title;
WindowPtr wind;
TWindow **info;
Rect r, arrowRect, backwardHotRect, forwardHotRect;
ControlHandle vScroll;
GrafPtr port;
ArrowPairRef helpArrowPair;
pictResID = item - gNumStandardHelpMenuItems +
kFirstHelpMenuPictResourceID - 1;
if (CheckHelpWindowAlreadyOpen(pictResID)) return noErr;
pict = GetPicture(pictResID);
GetResInfo((Handle)pict, &theID, &theType, title);
GetPort(&port);
err = CreateNewWindow(kHelp, title, "\pGeneva", 12, &wind);
if (err != noErr) return err;
SetPort(wind);
info = (TWindow**)GetWRefCon(wind);
(**info).pictResID = pictResID;
PositionNewWindow(wind, kMinWindowWidth, kMinWindowHeight);
SetRect(&r, kMinWindowWidth-15, kPanelHeight-1, kMinWindowWidth+1, kMinWindowHeight-14);
vScroll = NewControl(wind, &r, "\p", true, 0, 0, 0, scrollBarProc, 1);
(**info).vScroll = vScroll;
SetRect(&arrowRect, 10, 5, 32, 15);
SetRect(&backwardHotRect, 8, 3, 20, 19);
SetRect(&forwardHotRect, 24, 3, 35, 19);
err = CreateArrowPair(false, &arrowRect, &backwardHotRect,
&forwardHotRect, &helpArrowPair);
if (err != noErr) goto exit;
(**info).helpArrowPair = helpArrowPair;
EnableOrDisableArrowPair(helpArrowPair, -1,
pictResID > kFirstHelpMenuPictResourceID);
EnableOrDisableArrowPair(helpArrowPair, +1,
pictResID < kFirstHelpMenuPictResourceID + gNumHelpTopics - 1);
err = DoZoom(wind, inZoomOut);
if (err != noErr) goto exit;
AdjustScrollMax(wind);
MyShowWindow(wind);
SetPort(port);
return noErr;
exit:
DoClose(wind);
SetPort(port);
return err;
}
/*----------------------------------------------------------------------------
OpenFirstHelpTopicWindow
Open the first help topic window.
Exit: function result = error code.
----------------------------------------------------------------------------*/
OSErr OpenFirstHelpTopicWindow (void)
{
return DoHelpMenuCommand(gNumStandardHelpMenuItems + 1);
}
/*----------------------------------------------------------------------------
ChangeTopic
Go forward or backward one topic.
Entry: wind = pointer to help window.
dir = +1 to go foward one topic, -1 to go backward.
Exit: function result = error code.
----------------------------------------------------------------------------*/
static OSErr ChangeTopic (WindowPtr wind, short dir)
{
TWindow **info;
ControlHandle vScroll;
short pictResID;
PicHandle pict;
short theID;
ResType theType;
Str255 name;
info = (TWindow**)GetWRefCon(wind);
vScroll = (**info).vScroll;
pictResID = (**info).pictResID;
while (true) {
pictResID += dir;
if (pictResID < kFirstHelpMenuPictResourceID ||
pictResID >= kFirstHelpMenuPictResourceID + gNumHelpTopics)
{
SysBeep(0);
return noErr;
}
pict = GetPicture(pictResID);
GetResInfo((Handle)pict, &theID, &theType, name);
if (name[1] != '-') break;
}
SetWTitle(wind, name);
SetControlValue(vScroll, 0);
(**info).pictResID = pictResID;
EraseRect(&wind->portRect);
EnableOrDisableArrowPair((**info).helpArrowPair, -1,
pictResID > kFirstHelpMenuPictResourceID);
EnableOrDisableArrowPair((**info).helpArrowPair, +1,
pictResID < kFirstHelpMenuPictResourceID + gNumHelpTopics - 1);
DoZoom(wind, inZoomOut);
return noErr;
}
/*----------------------------------------------------------------------------
ResizeContents
Adjust a help window's contents after a window size change (grow
or zoom).
Entry: wind = pointer to help window.
----------------------------------------------------------------------------*/
static void ResizeContents (WindowPtr wind)
{
TWindow **info;
short width, height;
ControlHandle vScroll;
Rect r;
info = (TWindow**)GetWRefCon(wind);
vScroll = (**info).vScroll;
width = wind->portRect.right;
height = wind->portRect.bottom;
SetRect(&r, width-15, kPanelHeight-1, width+1, height-14);
(**vScroll).contrlRect = r;
AdjustScrollMax(wind);
InvalRect(&wind->portRect);
}
/*----------------------------------------------------------------------------
DoSave
Handle the "Save" command.
Entry: wind = pointer to help window.
modifiers = modifiers field from event record.
Exit: function result = error code.
----------------------------------------------------------------------------*/
static OSErr DoSave (WindowPtr wind, short modifiers)
{
Str255 title;
Str31 fileName;
StandardFileReply reply;
Str255 prompt;
OSErr err = noErr;
TWindow **info;
short refNum = 0;
Boolean empty;
short pictResID;
char zeros[0x200];
long length;
PicHandle pict;
GetWTitle(wind, title);
MakeLegalFileName(title, fileName);
GetPString(kStrSaveFileAsPrompt, prompt);
MyStandardPutFile(prompt, fileName, &reply, nil);
if (!reply.sfGood) return userCanceledErr;
info = (TWindow**)GetWRefCon(wind);
pictResID = (**info).pictResID;
err = OpenDataForkWriteCreateIfMissing(&reply.sfFile, 'ttxt', 'PICT',
reply.sfScript, false, &refNum, &empty);
if (err != noErr) goto exit;
memset(zeros, 0, sizeof(zeros));
length = sizeof(zeros);
err = FSWrite(refNum, &length, zeros);
if (err != noErr) goto exit;
pict = GetPicture(pictResID);
MyHLock(pict);
length = MyGetHandleSize(pict);
err = FSWrite(refNum, &length, *pict);
MyHUnlock(pict);
if (err != noErr) goto exit;
MyFSClose(refNum, nil);
return noErr;
exit:
if (refNum != 0) MyFSClose(refNum, nil);
return err;
}
/*----------------------------------------------------------------------------
DoSaveAs
Handle the "Save As" command.
Entry: wind = pointer to help window.
modifiers = modifiers field from event record.
Exit: function result = error code.
----------------------------------------------------------------------------*/
static OSErr DoSaveAs (WindowPtr wind, short modifiers)
{
return DoSave(wind, modifiers);
}
/*----------------------------------------------------------------------------
DoPrint
Handle the "Print" command.
Entry: wind = pointer to help window.
modifiers = modifiers field from event record.
Exit: function result = error code.
----------------------------------------------------------------------------*/
static OSErr DoPrint (WindowPtr wind, short modifiers)
{
TWindow **info;
CStr255 title;
OSErr err = noErr;
err = StartPrint();
if (err != noErr) return err;
err = DisplayStatusMessageNumber(kStrPrinting);
if (err != noErr) return err;
info = (TWindow**)GetWRefCon(wind);
GetWTitle(wind, (StringPtr)title);
p2cstr((StringPtr)title);
return PrintPict ((**info).pictResID, title);
}
/*----------------------------------------------------------------------------
Activate
Handle an activate event for a help window.
Entry: wind = pointer to help window.
act = true to activate, false to deactivate
----------------------------------------------------------------------------*/
static void Activate (WindowPtr wind, Boolean act)
{
TWindow **info;
ControlHandle vScroll;
Rect r;
info = (TWindow**)GetWRefCon(wind);
vScroll = (**info).vScroll;
if (act) {
ShowControl(vScroll);
} else {
HideControl(vScroll);
}
r = wind->portRect;
r.top = r.bottom - 15;
r.left = r.right - 15;
InvalRect(&r);
}
/*----------------------------------------------------------------------------
Update
Handle an update event for a help window.
Entry: wind = pointer to help window.
----------------------------------------------------------------------------*/
static void Update (WindowPtr wind)
{
TWindow **info;
PicHandle pict;
Rect dstRect, r;
short pos, windWidth;
ControlHandle vScroll;
info = (TWindow**)GetWRefCon(wind);
vScroll = (**info).vScroll;
pos = GetControlValue(vScroll);
r = wind->portRect;
r.top = kPanelHeight;
ClipRect(&r);
DrawGrowIcon(wind);
NoClip();
UpdateControls(wind, wind->visRgn);
windWidth = wind->portRect.right - wind->portRect.left;
MoveTo(0, kPanelHeight-3);
LineTo(windWidth, kPanelHeight-3);
MoveTo(0, kPanelHeight-1);
LineTo(windWidth, kPanelHeight-1);
DrawArrowPair((**info).helpArrowPair);
r = wind->portRect;
r.top = kPanelHeight;
r.bottom -= 15;
r.right -= 15;
InsetRect(&r, kTextMargin, kTextMargin);
ClipRect(&r);
pict = GetPicture((**info).pictResID);
HNoPurge((Handle)pict);
dstRect = (**pict).picFrame;
OffsetRect(&dstRect, -dstRect.left + kTextMargin,
-dstRect.top + kPanelHeight + kTextMargin - pos);
DrawPicture(pict, &dstRect);
HPurge((Handle)pict);
NoClip();
}
/*----------------------------------------------------------------------------
Mouse
Handle a mouse down event in the content area of a help window.
Entry: wind = pointer to text window.
where = location of mouse down in local coords.
modifiers = modifiers field from event record.
Exit: function result = error code.
----------------------------------------------------------------------------*/
static OSErr Mouse (WindowPtr wind, Point where, short modifiers)
{
TWindow **info;
short part, oldVal, dv, arrowTrackResult;
ControlHandle control, vScroll;
info = (TWindow**) GetWRefCon(wind);
vScroll = (**info).vScroll;
part = FindControl(where, wind, &control);
if (part != 0 && control == vScroll) {
if (part == inThumb) {
oldVal = GetControlValue(vScroll);
TrackControl(vScroll, where, nil);
dv = GetControlValue(vScroll) - oldVal;
if (dv != 0) Scroll(wind, -dv);
} else {
SetControlReference(vScroll, 0);
TrackControl(vScroll, where, gScrollActionUPP);
SetControlReference(vScroll, 1);
AdjustScrollMax(wind);
}
}
arrowTrackResult = TrackArrowPair((**info).helpArrowPair);
if (arrowTrackResult != 0) return ChangeTopic(wind, arrowTrackResult);
return noErr;
}
/*----------------------------------------------------------------------------
Draggable
Determine whether a mouse down event is on a draggable object in a
help window.
Entry: wind = pointer to text window.
where = location of mouse down event, in local coordinates.
modifiers = modifiers field from event record.
Exit: function result = true if object is draggable.
----------------------------------------------------------------------------*/
static Boolean Draggable (WindowPtr wind, Point where, short modifiers)
{
return false;
}
/*----------------------------------------------------------------------------
Key
Handle a key down event for a help window.
Entry: wind = pointer to help window.
theChar = ASCII code of key.
theKey = keyboard code of key.
modifiers = modifiers field from event record.
Exit: function result = error code.
----------------------------------------------------------------------------*/
static OSErr Key (WindowPtr wind, unsigned char theChar, unsigned char theKey,
short modifiers)
{
TWindow **info;
TKeypadKey keypadKey;
info = (TWindow**)GetWRefCon(wind);
if (gPrefs.keypadShortcuts && IsKeypadKey(theChar, theKey, &keypadKey)) {
switch (keypadKey) {
case kKeypadStarKey:
return DoClose(wind);
case kKeypad1Key:
ScrollByPartCode(wind, kScrollToEnd);
return noErr;
case kKeypad2Key:
ScrollByPartCode(wind, inDownButton);
return noErr;
case kKeypad3Key:
ScrollByPartCode(wind, inPageDown);
return noErr;
case kKeypad7Key:
ScrollByPartCode(wind, kScrollToHome);
return noErr;
case kKeypad8Key:
ScrollByPartCode(wind, inUpButton);
return noErr;
case kKeypad9Key:
ScrollByPartCode(wind, inPageUp);
return noErr;
default:
SysBeep(0);
return noErr;
}
}
if (theChar == pageUpKey) {
ScrollByPartCode(wind, inPageUp);
return noErr;
}
if (theChar == pageDownKey) {
ScrollByPartCode(wind, inPageDown);
return noErr;
}
if (theChar == homeKey) {
ScrollByPartCode(wind, kScrollToHome);
return noErr;
}
if (theChar == endKey) {
ScrollByPartCode(wind, kScrollToEnd);
return noErr;
}
if (theChar == leftArrow) {
/*FlashArrowPair((**info).helpArrowPair, -1) - tried this, didn't like it*/;
return ChangeTopic(wind, -1);
}
if (theChar == rightArrow) {
/*FlashArrowPair((**info).helpArrowPair, +1) - tried this, didn't like it*/;
return ChangeTopic(wind, +1);
}
if (gPrefs.keyboardShortcuts) {
if (theChar == ' ') {
ScrollByPartCode(wind, inPageDown);
return noErr;
}
theChar = tolower(theChar);
if (theChar == 'w') {
return DoClose(wind);
}
}
SysBeep(0);
return noErr;
}
/*----------------------------------------------------------------------------
Grow
Handle a mouse down event in the grow box of a help window.
Entry: wind = pointer to help window.
where = location of mouse down event, in global coordinates.
Exit: function result = error code.
----------------------------------------------------------------------------*/
static OSErr Grow (WindowPtr wind, Point where)
{
Rect sizeRect;
long size;
short width, height;
SetRect(&sizeRect, kMinWindowWidth, kMinWindowHeight, kMaxShort, kMaxShort);
size = GrowWindow(wind, where, &sizeRect);
if (size != 0) {
width = LoWord(size);
height = HiWord(size);
SizeWindow(wind, width, height, false);
ResizeContents(wind);
}
return noErr;
}
/*----------------------------------------------------------------------------
Zoom
Zoom a help window.
Entry: wind = pointer to help window.
zoomDir = zoom direction = inZoomIn or inZoomOut.
Exit: function result = error code.
----------------------------------------------------------------------------*/
static OSErr Zoom (WindowPtr wind, short zoomDir)
{
TWindow **info;
short width, height;
Rect zoomRect;
WStateData **wState;
PicHandle pict;
Rect picFrame;
wState = (WStateData**)((WindowPeek)wind)->dataHandle;
if (zoomDir == inZoomOut) {
info = (TWindow**)GetWRefCon(wind);
pict = GetPicture((**info).pictResID);
picFrame = (**pict).picFrame;
width = picFrame.right - picFrame.left + 15 + 2*kTextMargin;
if (width < kMinWindowWidth) width = kMinWindowWidth;
height = picFrame.bottom - picFrame.top + 15 + kPanelHeight + 2*kTextMargin;
if (height < kMinWindowHeight) height = kMinWindowHeight;
CalculateZoomRect(wind, width, height, &zoomRect, gPrefs.dontCoverFinderIcons);
(**wState).stdState = zoomRect;
if (WindRectEqualRect(wind, &zoomRect)) return noErr;
}
EraseRect(&wind->portRect);
ZoomWindow(wind, zoomDir, false);
ResizeContents(wind);
return noErr;
}
/*----------------------------------------------------------------------------
Command
Handle a command for a help window.
Entry: wind = pointer to help window.
menu = the menu.
item = the item.
modifiers = modifiers field from event record.
Exit: function result = error code.
----------------------------------------------------------------------------*/
static OSErr Command (WindowPtr wind, short menu, short item, short modifiers)
{
OSErr err = noErr;
switch (menu) {
case kFileMenu:
switch (item) {
case kSaveItem:
err = DoSave(wind, modifiers);
break;
case kSaveAsItem:
err = DoSaveAs(wind, modifiers);
break;
case kPrintItem:
err = DoPrint(wind, modifiers);
break;
}
break;
}
return err;
}
/*----------------------------------------------------------------------------
Close
Close a help window.
Entry: wind = pointer to help window.
Exit: function result = error code.
----------------------------------------------------------------------------*/
static OSErr Close (WindowPtr wind)
{
TWindow **info;
info = (TWindow**)GetWRefCon(wind);
DisposeArrowPair((**info).helpArrowPair);
MyDisposeHandle(info);
MyDisposeWindow(wind);
return noErr;
}
/*----------------------------------------------------------------------------
Idle
Handle idle time tasks for a help window.
Entry: wind = pointer to help window.
Exit: cursorRgn = cursor region for WaitNextEvent mouse moved events.
----------------------------------------------------------------------------*/
static void Idle (WindowPtr wind, RgnHandle cursorRgn)
{
unsigned long fileEnabled, specialEnabled;
SetCursor(&qd.arrow);
if (gStartupOK) {
specialEnabled = kHelpSpecialEnabled;
SetMenusTo(kAppleAllEnabled, kHelpFileEnabled, kHelpEditEnabled,
kHelpNewsEnabled, specialEnabled, kHelpWindEnabled);
} else {
fileEnabled = kHelpFileEnabled;
fileEnabled &= ~(kNewGroupWindowMask | kOpenMask);
SetMenusTo(kAppleAllEnabled, fileEnabled, kHelpEditEnabled,
kStartupBadNewsEnabled, kStartupBadSpecialEnabled, kStartupBadWindEnabled);
}
}
/*----------------------------------------------------------------------------
Help
Handle help balloons for a help window.
Entry: wind = pointer to help window.
where = current mouse location in local coordinates.
----------------------------------------------------------------------------*/
static void Help (WindowPtr wind, Point where)
{
TWindow **info;
Rect r;
Point tip = {0, 0};
short result;
Boolean enabled;
if (DoSizeBoxAndVerticalScrollBarBalloons(wind, where)) return;
info = (TWindow**)GetWRefCon(wind);
result = TestArrowPairHotRect((**info).helpArrowPair, where, &r, &enabled);
if (result != 0) {
if (enabled) {
ShowHelpBalloon(tip, &r, result == -1 ? 4 : 5);
} else {
ShowHelpBalloon(tip, &r, result == -1 ? 6 : 7);
}
return;
}
SetRect(&r, 0, kPanelHeight,
wind->portRect.right -15, wind->portRect.bottom - 15);
if (PtInRect(where, &r)) {
ShowHelpBalloon(where, &r, 24);
return;
}
}
/*----------------------------------------------------------------------------
InitHelpDispatchTable
Initialize the dispatch table for help windows.
----------------------------------------------------------------------------*/
void InitHelpDispatchTable (void)
{
TDispatch *d;
d = &gDispatch[kHelp];
d->activate = Activate;
d->update = Update;
d->mouse = Mouse;
d->draggable = Draggable;
d->key = Key;
d->grow = Grow;
d->zoom = Zoom;
d->command = Command;
d->close = Close;
d->idle = Idle;
d->help = Help;
gScrollActionUPP = NewControlActionProc(ScrollAction);
}